package com.example.onlinemonitoring.autoRun;

import com.example.onlinemonitoring.model.Appstation;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.LanguageManager;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.serviceImpl.AppdeviceServiceImpl;
import com.example.onlinemonitoring.serviceImpl.AppstationServiceImpl;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class ComRunner implements ApplicationRunner {

    @Autowired
    AppdeviceServiceImpl AppdeviceImpl; // 自动装配AppdeviceServiceImpl对象
    @Autowired
    AppstationServiceImpl appstationserviceimpl; // 自动装配AppstationServiceImpl对象
    @Autowired
    LanguageManager languageManager; // 自动装配LanguageManager对象
    // 当前开启的串口
    static ArrayList<String> comList = new ArrayList<>(); // 定义静态的ArrayList对象comList
    public static Integer Language = 0; // 定义静态的Integer对象Language并初始化为0
    public static ComTcp[] ct = new ComTcp[20]; // 定义长度为20的ComTcp数组对象ct
    public static ComTcp info = new ComTcp(); // 创建ComTcp对象info
    List<String> portlist = new ArrayList<>(); // 创建ArrayList对象portlist
    
    @Autowired
    private BeanFactory beanFactory; // 自动装配BeanFactory对象
    @Autowired
    private AsyncService asyncService; // 自动装配AsyncService对象
    @Autowired
    private ApplicationContext context; // 自动装配ApplicationContext对象

    @Value("${primary.datasource.druid.maxActive}")
    private int maxActive; // 从配置文件中获取maxActive的值并赋给maxActive变量

    public static volatile Map<Integer, CommPortManager> devmap = new ConcurrentHashMap<>(); // 创建volatile
                                                                                             // Map对象devmap并初始化为ConcurrentHashMap对象
    public static volatile Map<Integer, CommPortManager> netmap = new ConcurrentHashMap<>(); // 创建volatile
                                                                                             // Map对象netmap并初始化为ConcurrentHashMap对象
    public static volatile Map<Integer, Integer> netportmap = new ConcurrentHashMap<>(); // 创建volatile
                                                                                         // Map对象netportmap并初始化为ConcurrentHashMap对象
    public static volatile Map<Integer, CommPortManager> netservermap = new ConcurrentHashMap<>(); // 创建volatile
                                                                                                   // Map对象netservermap并初始化为ConcurrentHashMap对象

    // public Socket s;
    // public OutputStream outputStream = null;
    // InputStream inputStream = null;
    int index = 0; // 定义整型变量index并初始化为0
    // boolean flag = true;// 串口线程只启动一次

    /**
     * 启动方法
     *
     * @param args
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        for (int i = 0; i < maxActive; i++) { // 循环maxActive次
            ct[i] = new ComTcp(); // 创建ComTcp对象并赋给ct[i]
            ct[i].setPort(i + 8300); // 设置ct[i]的端口号
            ct[i].setIndex(i); // 设置ct[i]的索引
            ct[i].load(); // 调用ct[i]的load方法
            new Thread(ct[i]).start(); // 创建并启动线程，线程的任务是运行ct[i]
        }
        info.setPort(8299); // 设置info的端口号
        info.load(); // 调用info的load方法
        new Thread(info).start(); // 创建并启动线程，线程的任务是运行info
        asyncService.runAppNetdevice(); // 调用asyncService的runAppNetdevice方法
        asyncService.runAppNetServerdevice(); // 调用asyncService的runAppNetServerdevice方法
        asyncService.runApp61850Clientdevice(); // 调用asyncService的runApp61850Clientdevice方法
        asyncService.runAppUSBServerdevice(); // 调用asyncService的runAppUSBServerdevice方法
        asyncService.runAppModbustcpNetdevice();// 调用asyncService的runAppModbustcpNetdevice方法
        myInit(); // 调用myInit方法
        languageManager.myInit(Language); // 调用languagemanager的myInit方法，传入Language参数
    }

    /**
     * 启动所有串口设备
     *
     * @param index 串口序列号
     */
    public boolean runAppdevice(int index) {
        // 初始化设备实时列表
        Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
        Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
        criteria.andEqualTo("installed", 1); // 添加查询条件，installed等于1
        criteria.andEqualTo("communicationmode", 1); // 添加查询条件，communicationmode等于1
        criteria.andLike("com", "%" + CommPortManager.numGetStr(index)); // 添加查询条件，com字段以指定字符串结尾
        List<Appdevice> devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
        try {
            if (devicelist.size() >= 1) { // 如果列表不为空
                if (devmap.get(index) == null) { // 如果devmap中指定索引的值为空
                    devmap.put(index, (CommPortManager) context.getBean(devicelist.get(0).getSimple() + "Com")); // 将指定索引和对应的CommPortManager对象放入devmap中
                }
                CommPortManager ad_com = devmap.get(index); // 获取devmap中指定索引的CommPortManager对象
                // 打开串口
                ad_com.Initialize(devicelist.get(0)); // 调用CommPortManager对象的Initialize方法，传入Appdevice对象
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 初始化Language
     */
    public void myInit() {
        Appstation as = new Appstation(); // 创建Appstation对象as
        as.setId(1); // 设置as的id属性为1
        as = appstationserviceimpl.selectByPrimaryKey(as); // 根据主键查询as对象
        Language = as.getLanguage(); // 获取as对象的language属性值并赋给Language变量
    }

    @Service("asyncService")
    public class AsyncService {
        /**
         * 前端接口访问异步调用开关设备
         *
         * @param appdevice
         */
        private Set<Integer> ports = new HashSet<>(); // 创建HashSet对象ports

        @Async("threadPoolm")
        public void runAppdevice(Appdevice appdevice) { // 异步方法，接收Appdevice对象作为参数
            try {
                int index = CommPortManager.strGetNum(appdevice.getCom()); // 调用CommPortManager类的strGetNum方法，传入appdevice的com属性，返回整型值赋给index变量
                if (devmap.get(index) == null) { // 如果devmap中指定索引的值为空
                    devmap.put(index, (CommPortManager) context.getBean(appdevice.getSimple() + "Com")); // 将指定索引和对应的CommPortManager对象放入devmap中
                }

                CommPortManager ad_com = devmap.get(index); // 获取devmap中指定索引的CommPortManager对象
                // 打开串口
                if (appdevice.getCommunicationmode() == 1) { // 如果appdevice的communicationmode属性等于1
                    ad_com.Initialize(appdevice); // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                } else if (appdevice.getCommunicationmode() == 3) { // 如果appdevice的communicationmode属性等于3
                    // 打开网口
                    ad_com.Initialize(appdevice); // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                }
                Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 循环监测网口启动状态Modbustcp客户端
         */
        @Async("threadPoolm")
        public void runAppModbustcpNetdevice() {
            // 初始化设备实时列表
            Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
            Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
            List<Appdevice> devicelist;
            criteria.andEqualTo("communicationmode", 6); // 添加查询条件，communicationmode等于2
            Map<Integer, Long> timemap = new HashMap<>(); // 创建HashMap对象timemap
            Map<Integer, Boolean> boolmap = new HashMap<>(); // 创建HashMap对象boolmap

            while (true) {
                devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
                try {
                    for (int j = 0; j < devicelist.size(); j++) { // 遍历devicelist列表
                        Appdevice appdevice = devicelist.get(j); // 获取列表中指定索引的Appdevice对象
                        if ((new Date().getTime() - CommPortManager.isnull(timemap.get(appdevice.getId()))) < 30000
                                && !boolmap.get(appdevice.getId())) { // 如果满足条件
                            continue; // 跳过本次循环
                        }

                        CommPortManager ad_com = netmap.get(appdevice.getId()); // 获取netmap中指定索引的CommPortManager对象
                        if (appdevice.getInstalled() == 1 && ad_com == null) { // 如果appdevice的installed属性为1且ad_com为空
                            CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple() + "Com"); // 根据appdevice的simple属性获取对应的bean对象
                            appdevice.setLocalport(appdevice.getLocalport()
                                    + CommPortManager.isnull(netportmap.get(appdevice.getId()))); // 设置appdevice的localport属性为localport属性加上指定索引的netportmap值
                            // 打开网口
                            if (cp.Initialize(appdevice)) { // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                                netmap.put(appdevice.getId(), cp); // 将指定索引和对应的CommPortManager对象放入netmap中
                                cp.startSendThread(appdevice); // 调用CommPortManager对象的startSendThread方法，传入appdevice对象
                                cp.startReceiveThread(); // 调用CommPortManager对象的startReceiveThread方法
                            } else {
                                timemap.put(appdevice.getId(), new Date().getTime()); // 将指定索引和当前时间放入timemap中
                                boolmap.put(appdevice.getId(), false); // 将指定索引和false放入boolmap中
                                netportmap.put(appdevice.getId(),
                                        CommPortManager.isnull(netportmap.get(appdevice.getId())) + 1); // 将指定索引和指定索引的netportmap值加1放入netportmap中
                                if (netportmap.get(appdevice.getId()) > appdevice.getLocalport() + 2000
                                        || netportmap.get(appdevice.getId()) > 60000) { // 如果满足条件
                                    netportmap.put(appdevice.getId(), appdevice.getLocalport()); // 将指定索引和appdevice的localport属性值放入netportmap中
                                }
                            }
                        } else if (appdevice.getInstalled() == 0 && ad_com != null) { // 如果appdevice的installed属性为0且ad_com不为空
                            if (ad_com.Close()) { // 调用CommPortManager对象的Close方法
                                netmap.remove(appdevice.getId()); // 从netmap中移除指定索引的值
                            }
                        }
                        Thread.sleep(200); // 线程休眠200毫秒
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(200); // 线程休眠200毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        /**
         * 循环监测USB端口启动状态
         *
         * @param appdevice
         */
        @Async("threadPoolm")
        public void runAppUSBServerdevice() {
            Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
            Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
            criteria.andEqualTo("communicationmode", 5); // 添加查询条件，communicationmode等于5
            criteria.andLike("com", "%" + "USB0"); // 添加查询条件，com字段以指定字符串结尾
            List<Appdevice> devicelist;
            while (true) {
                devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
                try {
                    for (int j = 0; j < devicelist.size(); j++) { // 遍历devicelist列表
                        Appdevice appdevice = devicelist.get(j); // 获取列表中指定索引的Appdevice对象
                        CommPortManager ad_com = devmap.get(appdevice.getId()); // 获取devmap中指定索引的CommPortManager对象
                        if (appdevice.getInstalled() == 1 && ad_com == null) { // 如果appdevice的installed属性为1且ad_com为空
                            CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple() + "Com"); // 根据appdevice的simple属性获取对应的bean对象
                            // 打开网口
                            if (cp.Initialize(appdevice)) { // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                                devmap.put(appdevice.getId(), cp); // 将指定索引和对应的CommPortManager对象放入devmap中
                                cp.startSendThread(appdevice); // 调用CommPortManager对象的startSendThread方法，传入appdevice对象
                                // netservermap.put(appdevice.getId(), cp);
                            }
                        } else if (appdevice.getInstalled() == 0 && ad_com != null) { // 如果appdevice的installed属性为0且ad_com不为空
                            if (ad_com.Close()) { // 调用CommPortManager对象的Close方法
                                devmap.remove(appdevice.getId()); // 从devmap中移除指定索引的值
                            }
                        }
                        Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 循环监测网口启动状态
         *
         * @param appdevice
         */
        @Async("threadPoolm")
        public void runAppNetServerdevice() {
            Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
            Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
            criteria.andEqualTo("communicationmode", 3); // 添加查询条件，communicationmode等于3
            List<Appdevice> devicelist;
            while (true) {
                devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
                try {
                    for (int j = 0; j < devicelist.size(); j++) { // 遍历devicelist列表
                        Appdevice appdevice = devicelist.get(j); // 获取列表中指定索引的Appdevice对象
                        CommPortManager ad_com = netservermap.get(appdevice.getId()); // 获取netservermap中指定索引的CommPortManager对象
                        if (appdevice.getInstalled() == 1 && ad_com == null) { // 如果appdevice的installed属性为1且ad_com为空
                            CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple() + "Com"); // 根据appdevice的simple属性获取对应的bean对象
                            // 打开网口
                            if (cp.Initialize(appdevice)) { // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                                netservermap.put(appdevice.getId(), cp); // 将指定索引和对应的CommPortManager对象放入netservermap中
                                cp.startSendThread(appdevice); // 调用CommPortManager对象的startSendThread方法，传入appdevice对象
                            }
                        } else if (appdevice.getInstalled() == 0 && ad_com != null) { // 如果appdevice的installed属性为0且ad_com不为空
                            if (ad_com.Close()) { // 调用CommPortManager对象的Close方法
                                netservermap.remove(appdevice.getId()); // 从netservermap中移除指定索引的值
                            }
                        }
                        Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 循环监测网口启动状态
         */
        @Async("threadPoolm")
        public void runAppNetdevice() {
            // 初始化设备实时列表
            Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
            Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
            List<Appdevice> devicelist;
            criteria.andEqualTo("communicationmode", 2); // 添加查询条件，communicationmode等于2
            Map<Integer, Long> timemap = new HashMap<>(); // 创建HashMap对象timemap
            Map<Integer, Boolean> boolmap = new HashMap<>(); // 创建HashMap对象boolmap

            while (true) {
                devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
                try {
                    for (int j = 0; j < devicelist.size(); j++) { // 遍历devicelist列表
                        Appdevice appdevice = devicelist.get(j); // 获取列表中指定索引的Appdevice对象
                        if ((new Date().getTime() - CommPortManager.isnull(timemap.get(appdevice.getId()))) < 30000
                                && !boolmap.get(appdevice.getId())) { // 如果满足条件
                            continue; // 跳过本次循环
                        }

                        CommPortManager ad_com = netmap.get(appdevice.getId()); // 获取netmap中指定索引的CommPortManager对象
                        if (appdevice.getInstalled() == 1 && ad_com == null) { // 如果appdevice的installed属性为1且ad_com为空
                            CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple() + "Com"); // 根据appdevice的simple属性获取对应的bean对象
                            appdevice.setLocalport(appdevice.getLocalport()
                                    + CommPortManager.isnull(netportmap.get(appdevice.getId()))); // 设置appdevice的localport属性为localport属性加上指定索引的netportmap值
                            // 打开网口
                            if (cp.Initialize(appdevice)) { // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                                netmap.put(appdevice.getId(), cp); // 将指定索引和对应的CommPortManager对象放入netmap中
                                cp.startSendThread(appdevice); // 调用CommPortManager对象的startSendThread方法，传入appdevice对象
                                cp.startReceiveThread(); // 调用CommPortManager对象的startReceiveThread方法
                            } else {
                                timemap.put(appdevice.getId(), new Date().getTime()); // 将指定索引和当前时间放入timemap中
                                boolmap.put(appdevice.getId(), false); // 将指定索引和false放入boolmap中
                                netportmap.put(appdevice.getId(),
                                        CommPortManager.isnull(netportmap.get(appdevice.getId())) + 1); // 将指定索引和指定索引的netportmap值加1放入netportmap中
                                if (netportmap.get(appdevice.getId()) > appdevice.getLocalport() + 2000
                                        || netportmap.get(appdevice.getId()) > 60000) { // 如果满足条件
                                    netportmap.put(appdevice.getId(), appdevice.getLocalport()); // 将指定索引和appdevice的localport属性值放入netportmap中
                                }
                            }
                        } else if (appdevice.getInstalled() == 0 && ad_com != null) { // 如果appdevice的installed属性为0且ad_com不为空
                            if (ad_com.Close()) { // 调用CommPortManager对象的Close方法
                                netmap.remove(appdevice.getId()); // 从netmap中移除指定索引的值
                            }
                        }
                        Thread.sleep(200); // 线程休眠200毫秒
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(200); // 线程休眠200毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 循环监测61850客户端启动状态
         */
        @Async("threadPoolm")
        public void runApp61850Clientdevice() {
            // 初始化设备实时列表
            Example example = new Example(Appdevice.class); // 创建Example对象example，泛型为Appdevice类
            Example.Criteria criteria = example.createCriteria(); // 创建Criteria对象criteria
            criteria.andEqualTo("communicationmode", 4); // 添加查询条件，communicationmode等于4
            List<Appdevice> devicelist;
            Map<Integer, Long> timemap = new HashMap<>(); // 创建HashMap对象timemap
            Map<Integer, Boolean> boolmap = new HashMap<>(); // 创建HashMap对象boolmap
            while (true) {
                devicelist = AppdeviceImpl.selectByExample(example); // 查询满足条件的Appdevice对象列表
                try {
                    for (int j = 0; j < devicelist.size(); j++) { // 遍历devicelist列表
                        Appdevice appdevice = devicelist.get(j); // 获取列表中指定索引的Appdevice对象
                        if ((new Date().getTime() - CommPortManager.isnull(timemap.get(appdevice.getId()))) < 30000
                                && !boolmap.get(appdevice.getId())) { // 如果满足条件
                            continue; // 跳过本次循环
                        }
                        //System.out.printf("startReceive61850ClientThread：11" + appdevice.getName() + " ！ ");
                        CommPortManager ad_com = netmap.get(appdevice.getId()); // 获取netmap中指定索引的CommPortManager对象
                        if (appdevice.getInstalled() == 1 && ad_com == null) { // 如果appdevice的installed属性为1且ad_com为空
                            CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple() + "Com"); // 根据appdevice的simple属性获取对应的bean对象
                            // 打开网口
                           
                            if (cp.Initialize(appdevice)) { // 调用CommPortManager对象的Initialize方法，传入appdevice对象
                                netmap.put(appdevice.getId(), cp); // 将指定索引和对应的CommPortManager对象放入netmap中
                                //cp.startSendThread(appdevice);
                                System.out.printf("startReceive61850ClientThread：" + appdevice.getName() + " ！ ");
                                cp.startReceive61850ClientThread(); // 调用CommPortManager对象的startReceive61850ClientThread方法
                            } else {
                                timemap.put(appdevice.getId(), new Date().getTime()); // 将指定索引和当前时间放入timemap中
                                boolmap.put(appdevice.getId(), false); // 将指定索引和false放入boolmap中
                                cp.startSendThread(appdevice); // 调用CommPortManager对象的startSendThread方法，传入appdevice对象
                            }

                        } else if (appdevice.getInstalled() == 0 && ad_com != null) { // 如果appdevice的installed属性为0且ad_com不为空
                            if (ad_com.Close()) { // 调用CommPortManager对象的Close方法
                                netmap.remove(appdevice.getId()); // 从netmap中移除指定索引的值
                            }
                        }
                        Thread.sleep(300 * 3); // 线程休眠300 * 3毫秒
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(3000 * 3); // 线程休眠300 * 3毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 主要开始方法
         *
         * @param port 端口号
         */
        public void start(int port) {
            Runtime runtime = Runtime.getRuntime(); // 获取当前应用程序的运行时对象
            try {
                // 查找进程号
                Process p = runtime.exec(String.format("cmd /c netstat -ano | findstr %d", port)); // 执行命令行命令，查找指定端口号的进程
                InputStream is = p.getInputStream(); // 获取进程的输入流
                List<String> read = read(is, "UTF-8"); // 读取输入流的每一行数据
                if (read.size() == 0) { // 如果读取的数据为空
                    System.out.printf("找不到 %d 端口号的进程，继续执行...%n", port);
                } else {
                    System.out.printf("找到 %d 个进程，准备清理...%n", read.size());
                    toSet(read); // 将读取的数据转换为Set集合
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * 读取输入流的每一行代码
         *
         * @param in      InputStream
         * @param charset 字符集
         * @return 每一行数据的List
         */
        private List<String> read(InputStream in, String charset) throws IOException {
            List<String> data = new ArrayList<>(); // 创建ArrayList对象data
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); // 创建BufferedReader对象reader
            String line;
            while ((line = reader.readLine()) != null) { // 读取输入流的每一行数据
                boolean validPort = validPort(line); // 判断是否为指定端口
                if (validPort) { // 如果是指定端口
                    data.add(line); // 将行数据添加到data中
                }
            }
            reader.close(); // 关闭BufferedReader对象
            return data; // 返回data列表
        }

        /**
         * 使用正则表达式执行是否为指定端口，findstr会将包含的所有端口都找出来 例如：80也会包含8083
         *
         * @param str 每一行
         * @return 端口是否有效
         */
        private boolean validPort(String str) {
            Pattern pattern = Pattern.compile("^ *[a-zA-Z]+ +\\S+"); // 创建Pattern对象，用于匹配指定正则表达式
            Matcher matcher = pattern.matcher(str); // 创建Matcher对象，用于进行匹配

            if (!matcher.find())
                return false;
            String find = matcher.group(); // 获取匹配的字符串
            int lIndex = find.lastIndexOf(":");
            find = find.substring(lIndex + 1); // 获取端口号
            int port;
            try {
                port = Integer.parseInt(find); // 将端口号转换为整型
            } catch (NumberFormatException e) {
                System.out.println("查找到错误端口: " + find);
                return false;
            }
            return this.ports.contains(port); // 判断端口是否在ports集合中
        }

        /**
         * 将每一行进程信息的List转换为只有端口号的Set(去重)
         *
         * @param data 包含有全部端口信息的每一行数据list
         */
        private void toSet(List<String> data) {
            Set<Integer> pids = new HashSet<>(); // 创建HashSet对象pids
            for (String line : data) { // 遍历data列表
                int lIndex = line.lastIndexOf(" ");
                String spid = line.substring(lIndex + 1).trim(); // 获取进程号
                int pid;
                try {
                    pid = Integer.parseInt(spid); // 将进程号转换为整型
                    pids.add(pid); // 添加进程号到pids集合中
                } catch (NumberFormatException e) {
                    System.out.println("获取进程号错误: " + spid);
                }
                kill(pids); // 调用kill方法，传入pids集合
            }
        }

        /**
         * 一次性kill所有端口
         *
         * @param pids 端口集合
         */
        private void kill(Set<Integer> pids) {
            for (Integer pid : pids) { // 遍历pids集合
                try {
                    Process process = Runtime.getRuntime().exec(String.format("taskkill /F /pid %d", pid)); // 执行命令行命令，结束指定进程
                    InputStream is = process.getInputStream(); // 获取进程的输入流

                    String txt = readTxt(is, "GBK"); // 读取输入流的文本内容
                    System.out.println(txt); // 打印文本内容
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 读取输入流的文本内容
         *
         * @param in 输入流，charset
         */
        private String readTxt(InputStream in, String charset) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); // 创建BufferedReader对象reader
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) { // 读取输入流的每一行数据
                sb.append(line); // 添加行数据到sb中
            }
            reader.close(); // 关闭BufferedReader对象
            return sb.toString(); // 返回sb的字符串表示形式
        }
    }
}
